package ua.kiev.tosik.price.gui;

import org.apache.log4j.Logger;
import ua.kiev.tosik.price.Main;
import ua.kiev.tosik.price.conf.AppConfig;
import ua.kiev.tosik.price.conf.Language;
import ua.kiev.tosik.price.conf.Skin;
import ua.kiev.tosik.price.conf.SkinsConfig;
import ua.kiev.tosik.price.database.connectors.ConnectorFactory;
import ua.kiev.tosik.price.database.connectors.IConnector;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

public class MainMenu {

	private static MainMenu ourInstance;
	private static Logger logger = Logger.getLogger(MainMenu.class);
	private JMenuBar menuBar;
	private JMenu fileMenu;
	private JMenu optionMenu;
	private JMenuItem currentSkinMenu;

	private JMenuItem myProfileMenu;
	private JMenuItem exitMenu;

	private JMenuItem settingsMenu;
	private JMenu skinsMenu;
	private JMenuItem aboutMenu;

	private JCheckBoxMenuItem tasksCheckBox;

	private Language lang;

	private java.util.List<JMenuItem> fMenuList = new ArrayList<JMenuItem>();

	private ActionListener aboutMenuAction;
	private ActionListener exitFromApplication;
	private ActionListener tasksCheckBoxAction;

	public static MainMenu getInstance() {
		if (ourInstance == null) {
			ourInstance = new MainMenu();
		}
		return ourInstance;
	}

	public JMenuBar getMenuBar() {
		return menuBar;
	}

	private MainMenu() {
		logger.debug("Initialize main menu");
		lang = Language.getInstance();
		initActions();
		menuBar = new JMenuBar();
		fileMenu = new JMenu();
		createFileMenu(fileMenu);
		optionMenu = new JMenu();
		createOptionMenu(optionMenu);
		menuBar.add(fileMenu);
		menuBar.add(optionMenu);
		updateLocale();

		fMenuList.add(exitMenu);
		fMenuList.add(aboutMenu);

	}

	private void createFileMenu(JMenu fileMenu) {
		myProfileMenu = new JMenuItem();
		exitMenu = new JMenuItem();
		exitMenu.addActionListener(exitFromApplication);
		fileMenu.add(myProfileMenu);
		fileMenu.addSeparator();
		fileMenu.add(exitMenu);
	}

	private void createOptionMenu(JMenu optionMenu) {

		tasksCheckBox = new JCheckBoxMenuItem();

		tasksCheckBox.addActionListener(tasksCheckBoxAction);
		tasksCheckBox.setSelected(true);

		settingsMenu = new JMenuItem();
		skinsMenu = new JMenu();
		aboutMenu = new JMenuItem();
		aboutMenu.addActionListener(aboutMenuAction);
		fillSkinList(skinsMenu);
		optionMenu.add(tasksCheckBox);
		optionMenu.add(settingsMenu);
		optionMenu.add(skinsMenu);
		optionMenu.addSeparator();
		optionMenu.add(aboutMenu);
	}

	private void fillSkinList(JMenu skinsMenu) {
		for ( final Skin s: SkinsConfig.getInstance().getSkinList() ) {
			skinsMenu.add(
				new JMenuItem(s.getName()) {
					{
						if ( s.isSelected() ) {
							this.setFont(getFont().deriveFont(Font.BOLD));
							currentSkinMenu = this;
						}
						this.setActionCommand( s.getName() );
						this.addActionListener( new SkinSwitchCommand(s) );
					}
				}
			);
		}
	}

	public List<JMenuItem> getfMenuList() {
		return fMenuList;
	}

	private void initActions() {
		exitFromApplication = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.getInstance().exit();
			}
		};
		aboutMenuAction = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				showAboutDialog();
			}
		};
		tasksCheckBoxAction = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if ( tasksCheckBox.isSelected() ) {
					TaskMenuPanel.getInstance().getTaskPanel().setVisible(true);
				} else {
					TaskMenuPanel.getInstance().getTaskPanel().setVisible(false);
				}
			}
		};
	}

	private void showAboutDialog() {
		String dbString = "";
		try {
			NumberFormat numberFormat = new DecimalFormat("#,###");
			IConnector db = ConnectorFactory.getInstance(AppConfig.getInstance().get("app.dbtype"));
			dbString = "<html><b>Database:</b> <u>" + AppConfig.getInstance().get("app.dbtype") + "</u> ( " + numberFormat.format(db.getDatabaseSize()) + " Kb ):"; //<br/><strong>Hardware Id:</strong> " + Main.M_ID  + "</html>";
		} catch (ConnectorFactory.IllegalDbType illegalDbType) {
			logger.error(illegalDbType.getMessage(), illegalDbType);
		}
		Object[] aboutString = {lang.get("app.about.message"), dbString};
		JOptionPane.showMessageDialog(
			MainWindow.getInstance().getFrame(),
			aboutString,
			lang.get("app.about.title"),
			JOptionPane.OK_OPTION,
			new ImageIcon(lang.get("app.about.icon"))
		);
	}

	public void updateLocale() {

		fileMenu.setText(lang.get("app.menu.file.text"));
		optionMenu.setText(lang.get("app.menu.option.text"));

		myProfileMenu.setText(lang.get("app.menu.file.profile.text") + " ..");
		exitMenu.setText(lang.get("app.menu.file.exit"));
		settingsMenu.setText(lang.get("app.menu.option.settings") + " ..");
		skinsMenu.setText(lang.get("app.menu.option.skins"));
		aboutMenu.setText(lang.get("app.menu.option.about") + " ..");

		tasksCheckBox.setText(lang.get("app.menu.tasks.text"));

		tasksCheckBox.setIcon( new ImageIcon(lang.get("app.taskpanel.info.title.icon")));
		myProfileMenu.setIcon( new ImageIcon(lang.get("app.menu.file.profile.icon")) );
		exitMenu.setIcon( new ImageIcon(lang.get("app.menu.file.exit.icon")) );
		settingsMenu.setIcon( new ImageIcon(lang.get("app.menu.option.settings.icon")) );
		skinsMenu.setIcon( new ImageIcon(lang.get("app.menu.option.skins.icon")) );
		aboutMenu.setIcon( new ImageIcon(lang.get("app.menu.option.about.icon")) );
	}


	private class SkinSwitchCommand implements ActionListener {
		private Skin skin;
		public SkinSwitchCommand(Skin skin) {
			this.skin = skin;
		}
		public void actionPerformed(ActionEvent ae) {
			Main.switchSkin(skin);
			currentSkinMenu.setFont( currentSkinMenu.getFont().deriveFont(Font.PLAIN) );
			((JMenuItem)ae.getSource()).setFont(((JMenuItem)ae.getSource()).getFont().deriveFont(Font.BOLD));
			currentSkinMenu = ((JMenuItem)ae.getSource());
		}
	}

}